package zd.vrp.ga;

import java.util.ArrayList;
import java.util.List;

import zd.vrp.utils.SortObject;

public class Selection {
	public static int susNPointers = 6;

	// stochastically universally selection
	public static void sus(double[] fitness) {

		// calculate total fitness
		double totalFitness = 0.0;
		double[] totalFitnessArray = new double[fitness.length];
		for (int i = 0; i < fitness.length; i++) {
			totalFitness += fitness[i];
			totalFitnessArray[i] = totalFitness;
		}

		// startRand
		double step = totalFitness / susNPointers;
		double startRand = Math.random() * step;
		
		int initIndex = 0;
		int initI = 0;
		double fitnessPrevious = 0;
		double fitnessFollowing = 0;
		
		List<SortObject> soList = new ArrayList<SortObject>();
		
		while(startRand+initI*step < totalFitness){
			for(int i=0;i<totalFitnessArray.length;i++){
				if(totalFitnessArray[i]>startRand+initI*step){
					System.out.println(i);
					initI++;
					SortObject so = new SortObject();
					so.setPosition(i);
					so.setValue(fitness[i]);
					soList.add(so);
					break;
				}
			}
		}
		
		routtleWheel(soList);
	}

	public static void routtleWheel(List<SortObject> soList) {
		double totalFitness = 0;
		double tempTotalFitness = 0;

		int firstParent = 0;
		int secondParent = 0;

		for (int i = 0; i < soList.size(); i++) {
			totalFitness += soList.get(i).getValue();
		}
		System.out.println("total fitness:"+totalFitness);
		double rand = Math.random() * totalFitness;

		for (int i = 0; i < soList.size(); i++) {
			tempTotalFitness += soList.get(i).getValue();
			if (tempTotalFitness > rand) {
				firstParent = soList.get(i).getPosition();
				totalFitness -= soList.get(i).getValue();
				soList.remove(i);
				break;
			}
		}

		rand = Math.random() * totalFitness;

		for (int i = 0; i < soList.size(); i++) {
			tempTotalFitness += soList.get(i).getValue();
			if (tempTotalFitness > rand) {
				secondParent = soList.get(i).getPosition();			
				break;
			}
		}
		
		System.out.println("first parent:"+firstParent+"   second parent:"+secondParent);
	}

	public static void main(String[] args) {
		double[] d = { 1.6, 1.536842105263158, 1.473684210526316,
				1.4105263157894736, 1.3473684210526315, 1.2842105263157895,
				1.2210526315789474, 1.1578947368421053, 1.094736842105263,
				1.0315789473684212, 0.968421052631579, 0.9052631578947368,
				0.8421052631578947, 0.7789473684210526, 0.7157894736842104,
				0.6526315789473683, 0.5894736842105261, 0.5263157894736843,
				0.4631578947368422, 0.3999999999999999 };
		
		for(int i=0;i<10;i++){
			System.out.println("*******round"+i+"**************");
			sus(d);
			System.out.println("*******************************");
		}
		
	}
}
